/* linux-sio.c --- communication with gsm module via serial port */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <fcntl.h>
#include <termios.h>
#include <pthread.h>
#include "cutils/properties.h"
#include "modemcontrol.h"
#include "atchannel.h"

#include <utils/Log.h>
#define LOG_TAG "IMEI"
#define MODEM_PROP_NAME "ro.baseband"

static int modem_reset()
{
	int fd = 0;

	fd = open("/dev/modem", O_RDWR);

	ioctl(fd, MODEM_RESET);
	close (fd);
	sleep(5);

	return 1;
}

static int modem_poweroff()
{
	int fd = 0;

	fd = open("/dev/modem", O_RDWR);

	ioctl(fd, MODEM_PWR_OFF);
	close (fd);
	sleep(3);

	return 1;
}

static int modem_poweron()
{
	int fd = 0;

	fd = open("/dev/modem", O_RDWR);

	ioctl(fd, MODEM_PWR_ON);
	close (fd);
	sleep(5);

	return 1;
}

static void m1190_gsm_power_init()
{
	//modem_poweron();
	modem_reset();

	return;
}

static void m7281_wcdma_power_init()
{
	modem_poweron();

	return;
}

static void tw_wcdma_power_init()
{
	modem_poweroff();
	modem_poweron();
	modem_reset();

	return;
}

static void imei_set_result(int code)
{
	if(code == 1)
	{
		ALOGD("IMEI: 1\n");
		printf("IMEI: 1\n");
	}
	else
	{
		ALOGD("IMEI: 0\n");
		printf("IMEI: 0\n");
	}
}

static void m7281_imei_set(const char* port, const char* imei)
{
	char cmd[128] = {0};
	ATResponse* p_resp = NULL;
	ATChannel* channel = at_channel_create(PORT_TYPE_SERIAL, port,
					NULL, NULL);

	at_channel_open(channel);
	sleep(1);
	snprintf(cmd, 127, "AT+SPIMEI=\"%s\"", imei);
	do
	{
		if(!at_command_exec_for_result(channel, cmd, 5000))
		{
			imei_set_result(0);
			break;
		}
		
		snprintf(cmd, 127, "AT+CGSN");
		if(at_send_command_numeric(channel, cmd, 5000,  &p_resp) < 0 || p_resp->success == 0)
		{
			imei_set_result(0);
			break;
		}
		
		if(p_resp->p_intermediates->line != NULL && strcmp(p_resp->p_intermediates->line, imei) == 0)
		{
			imei_set_result(1);
		}
		else
		{
			imei_set_result(0);
		}
	}while(0);
	
	at_response_free(p_resp);
	at_channel_close(channel);
	at_channel_destroy(channel);

	return;
}

static void m7281_imei_get(const char* port)
{
	char cmd[128] = {0};
	ATResponse* p_resp = NULL;

	ATChannel* channel = at_channel_create(PORT_TYPE_SERIAL, port,
					NULL, NULL);
	at_channel_open(channel);

	sleep(1);
	do
	{
		snprintf(cmd, 127, "AT+CGSN");
		if(at_send_command_numeric(channel, cmd, 5000,  &p_resp) < 0 || p_resp->success == 0)
		{
			imei_set_result(0);
			break;
		}
		
		if(p_resp->p_intermediates->line != NULL) 
		{
			ALOGD("IMEI: %s\n", p_resp->p_intermediates->line);
		}
	}while(0);
	
	at_response_free(p_resp);
	at_channel_close(channel);
	at_channel_destroy(channel);

	return;
}
static void m1190_imei_set(const char* port, const char* imei)
{
	char cmd[128] = {0};
	ATResponse* p_resp = NULL;
	ATChannel* channel = at_channel_create(PORT_TYPE_SERIAL, port,
					NULL, NULL);

	at_channel_open(channel);
	sleep(1);
	snprintf(cmd, 127, "AT+SGMR=0,1,1,\"%s\"", imei);
	do
	{
		if(!at_command_exec_for_result(channel, cmd, 5000))
		{
			imei_set_result(0);
			break;
		}
		
		snprintf(cmd, 127, "AT+CGSN");
		if(at_send_command_numeric(channel, cmd, 5000,  &p_resp) < 0 || p_resp->success == 0)
		{
			imei_set_result(0);
			break;
		}
		
		if(p_resp->p_intermediates->line != NULL && strcmp(p_resp->p_intermediates->line, imei) == 0)
		{
			imei_set_result(1);
		}
		else
		{
			imei_set_result(0);
		}
	}while(0);
	
	at_response_free(p_resp);
	at_channel_close(channel);
	at_channel_destroy(channel);

	return;
}

static void m1190_imei_get(const char* port)
{
	char cmd[128] = {0};
	ATResponse* p_resp = NULL;

	ATChannel* channel = at_channel_create(PORT_TYPE_SERIAL, port,
					NULL, NULL);
	at_channel_open(channel);

	sleep(1);
	do
	{
		snprintf(cmd, 127, "AT+CGSN");
		if(at_send_command_numeric(channel, cmd, 5000,  &p_resp) < 0 || p_resp->success == 0)
		{
			imei_set_result(0);
			break;
		}
		
		if(p_resp->p_intermediates->line != NULL) 
		{
			ALOGD("IMEI: %s\n", p_resp->p_intermediates->line);
		}
	}while(0);
	
	at_response_free(p_resp);
	at_channel_close(channel);
	at_channel_destroy(channel);

	return;
}

static void tw_wcdma_imei_get(const char* port)
{
	char cmd[128] = {0};
	ATResponse* p_resp = NULL;
	ATChannel* channel = at_channel_create(PORT_TYPE_SERIAL, port,
					NULL, NULL);
	at_channel_open(channel);
	do
	{
		snprintf(cmd, 127, "AT^IMEI");
		if(at_send_command_numeric(channel, cmd, 5000,  &p_resp) < 0 || p_resp->success == 0)
		{
			imei_set_result(0);
			break;
		}
		
		if(p_resp->p_intermediates->line != NULL) 
		{
			ALOGD("IMEI: %s\n", p_resp->p_intermediates->line);
		}
	}while(0);
	
	at_response_free(p_resp);
	at_channel_close(channel);
	at_channel_destroy(channel);

	return;
}

static void tw_wcdma_imei_set(const char* port, const char* imei)
{
	char cmd[128] = {0};
	ATResponse* p_resp = NULL;
	ATChannel* channel = at_channel_create(PORT_TYPE_SERIAL, port,
					NULL, NULL);
	at_channel_open(channel);
	snprintf(cmd, 127, "AT^IMEI=%s", imei);
	do
	{
		if(!at_command_exec_for_result(channel, cmd, 5000))
		{
			imei_set_result(0);
			break;
		}
		
		snprintf(cmd, 127, "AT^IMEI");
		if(at_send_command_numeric(channel, cmd, 5000,  &p_resp) < 0 || p_resp->success == 0)
		{
			imei_set_result(0);
			break;
		}
		
		if(p_resp->p_intermediates->line != NULL && strcmp(p_resp->p_intermediates->line, imei) == 0)
		{
			imei_set_result(1);
		}
		else
		{
			imei_set_result(0);
		}
	}while(0);
	
	at_response_free(p_resp);
	at_channel_close(channel);
	at_channel_destroy(channel);

	return;
}

static void imei_set(const char* port, const char* imei)
{
	char modem[PROPERTY_VALUE_MAX] = {0};

	property_get(MODEM_PROP_NAME, modem, "");
	ALOGD("%s imei:%s to %s ", __func__, imei, modem);
	if(strcmp(modem, "tw_wcdma") == 0)
	{
		tw_wcdma_power_init();
		sleep(5);
		tw_wcdma_imei_set(port, imei);
	}
    else if(strcmp(modem, "m1190_gsm") == 0 || strcmp(modem, "m0282_gsm") == 0)   //broncho modify by lyl
	{
		m1190_gsm_power_init();
		m1190_imei_set(port, imei);
	}
	else if(strcmp(modem, "m7281_wcdma") == 0)
	{
		m7281_wcdma_power_init();
		m7281_imei_set(port, imei);
	}
	else
	{
		imei_set_result(0);
	}

	return;
}

static void imei_get(const char* port)
{
	char modem[PROPERTY_VALUE_MAX] = {0};

	property_get(MODEM_PROP_NAME, modem, "");
	ALOGD("%s imei from %s ", __func__, modem);
	if(strcmp(modem, "tw_wcdma") == 0)
	{
		tw_wcdma_power_init();
		sleep(5);
		tw_wcdma_imei_get(port);
	}
    else if(strcmp(modem, "m1190_gsm") == 0 || strcmp(modem, "m0282_gsm") == 0)   //broncho modify by lyl
	{
		m1190_gsm_power_init();
		m1190_imei_get(port);
	}
	else if(strcmp(modem, "m7281_wcdma") == 0)
	{
		m7281_wcdma_power_init();
		m7281_imei_get(port);
	}

	return;
}

static void print_useage(const char* exec)
{
	ALOGD("%s port_name get/set imei\n", exec);

	return;
}

int main(int argc, char** argv)
{
	int i = 0;

	if(argc == 3 && strcmp(argv[2], "get") == 0)
	{
		imei_get(argv[1]);
	}
	else if(argc == 4 && strcmp(argv[2], "set") == 0)
	{
		imei_set(argv[1], argv[3]);
	}
	else 
	{
		print_useage(argv[0]);
	}

	return 0;
}


